/*
 * invulgotracker
 * Copyright (C) Thomas Andersen 2011 <thomas.1.andersen@gmail.com>
 *
 * invulgotracker is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * invulgotracker is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>

#include "invulgotrackerapp.h"
#include "config.h"
#include "gettextmacro.h"
#include "prefs.h"
#include "prefs.h"
#include "about.h"
#include "report.h"
#include "taskid.h"
#include "recenttasks.h"
#include "workbalance.h"
#include <gdk/gdkkeysyms.h>
#include <libgnomevfs/gnome-vfs.h>
#include "taskdetaildlg.h"
#define _MULTI_THREADED
#include <pthread.h>





#define GLADE_FILE PACKAGE_DATA_DIR"/invulgotracker/glade/invulgotracker.glade"


GladeXML *InvulgoTrackerApp::gxml = NULL;
InvulgoTrackerApp *InvulgoTrackerApp::app = NULL;
bool visible = FALSE;


InvulgoTrackerApp::InvulgoTrackerApp()
{
    app = this;
    trayIcon = NULL;
    timeUsedCalc = NULL;
}

InvulgoTrackerApp::~InvulgoTrackerApp()
{
    app = NULL;
    if (timeUsedCalc)
        delete timeUsedCalc;
}


void InvulgoTrackerApp::CreateMainWindow()
{
    GtkWidget *view;

    /* Process glade file. */
    gxml = glade_xml_new (GLADE_FILE, NULL, GETTEXT_PACKAGE);
    glade_xml_signal_autoconnect (gxml);
    mainWindow = glade_xml_get_widget (gxml, "InvulgoTracker");

    /* Init time view */
    view = glade_xml_get_widget (gxml, "treeviewTime");
    TaskTime curr;
    timeView.SetDate(curr.GetYear(),curr.GetMonth(),curr.GetDay());
    timeView.Init(view);

    /* Init task view */
    view = glade_xml_get_widget (gxml, "treeviewTask");
    taskView.Init(view);

    /* Save statusbar. */
    statusBar = glade_xml_get_widget (gxml, "statusbarMain");


    /* Init summary view */
    view = glade_xml_get_widget (gxml, "treeviewSummary");
    summaryView.Init(view, TRUE, TRUE);
    UpdateSummary(curr.GetYear(), curr.GetMonth(), curr.GetDay());

    GtkCalendar *calendar = (GtkCalendar*)glade_xml_get_widget (gxml, "calendar");
    /* GtkCalendar widget changed - has to set the current date myself. */
    gtk_calendar_select_month(calendar, curr.GetMonth(), curr.GetYear());
    gtk_calendar_select_day(calendar, curr.GetDay());

}

void InvulgoTrackerApp::SetSavedSizes()
{
    Prefs prefs;

    /* Check if we should use the sizes at all. */
    if (prefs.GetSaveWindowSizes()) {
        /* Set width & height of main window. */
        if (prefs.GetSavedWindowWidth() != 0 && prefs.GetSavedWindowHeight() != 0)
            gtk_window_resize(GTK_WINDOW(mainWindow), prefs.GetSavedWindowWidth(), prefs.GetSavedWindowHeight());
        /* Set maximize state. */
        if (prefs.GetSavedWindowMaximized())
            gtk_window_maximize(GTK_WINDOW(mainWindow));
        /* Set v pane position. */
        if (prefs.GetSavedVPanePosition() != 0) {
            GtkWidget *window = glade_xml_get_widget (gxml, "vpanedTimeDate");
            gtk_paned_set_position(GTK_PANED(window), prefs.GetSavedVPanePosition());
        }
        /* Set h pane position. */
        if (prefs.GetSavedHPanePosition() != 0) {
            GtkWidget *window = glade_xml_get_widget (gxml, "hpanedTaskTime");
            gtk_paned_set_position(GTK_PANED(window), prefs.GetSavedHPanePosition());
        }
    }
}


#if GTK_CHECK_VERSION(2,12,0)
void InvulgoTrackerApp::SetTooltip(GtkTooltip *tooltip)
#else
void InvulgoTrackerApp::SetTooltip(GtkTooltips *tooltip)
#endif
{
    gchar *name;

    if (trayIcon && (const gchar *)lastTaskId && taskView.Get(lastTaskId, &name)) {
        gchar *line = new gchar[1001];
        TaskTime tt;
        TaskTime diff = tt.SubTime(lastTaskTime);
        char *timeStr = diff.TimeText();
        sprintf(line, "<b>InvulgoTracker</b>\n%s %s", name, timeStr);
        free(timeStr);
        g_free(name);
#if GTK_CHECK_VERSION(2,12,0)
        gtk_tooltip_set_markup(tooltip, line);
#else
        gtk_status_icon_set_tooltip(trayIcon, line);
#endif
        //gtk_status_icon_set_tooltip_markup(trayIcon, line);
        delete[] line;
    } else if (trayIcon) {
#if GTK_CHECK_VERSION(2,12,0)
        gtk_tooltip_set_markup(tooltip, "<b>InvulgoTracker</b>");
#else
        gtk_status_icon_set_tooltip(trayIcon, "InvulgoTracker");
#endif
        }
}


void InvulgoTrackerApp::Exit()
{
    GtkWidget *dlg = taskView.GetCurrentDlg();
    if (dlg)
        gtk_dialog_response(GTK_DIALOG(dlg), GTK_RESPONSE_CANCEL);
    dlg = timeView.GetCurrentDlg();
    if (dlg)
        gtk_dialog_response(GTK_DIALOG(dlg), GTK_RESPONSE_CANCEL);
    gtk_main_quit();
}

bool InvulgoTrackerApp::BlockMenu()
{
    if (taskView.GetCurrentDlg() || timeView.GetCurrentDlg())
        return true;
    return false;
}


static list<TaskId *> menuTaskList;

static GdkWindowState currentState;

extern "C" void on_about_activate(GtkButton *button, gpointer user_data)
{
    InvulgoTrackerApp::app->AboutShow();
}

extern "C" void on_help_activate(GtkButton *button, gpointer user_data)
{
    InvulgoTrackerApp::app->HelpShow();
}

extern "C" void on_toolbuttonAbout_clicked(GtkButton *button, gpointer user_data)
{
    InvulgoTrackerApp::app->AboutShow();
}

extern "C" void destroy (GtkWidget *widget, gpointer data)
{
    InvulgoTrackerApp::app->Exit();
}

extern "C" void tray_icon_on_click(GtkStatusIcon *status_icon,
                        gpointer user_data)
{
        if (visible) {
                gtk_widget_hide(GTK_WIDGET(user_data));
        } else {
                gtk_widget_show(GTK_WIDGET(user_data));
                gtk_window_present(GTK_WINDOW(user_data));
        }
        visible = !visible;
}

extern "C" void popupmenu_taskselect(GtkWidget *widget, gpointer data)
{
    InvulgoTrackerApp::app->AddTimeByTask(*((TaskId*)data));
}


static void MenuListClear()
{
    list<TaskId *>::const_iterator it;

    for(it = menuTaskList.begin();it != menuTaskList.end(); ++it) {
        delete *it;
    }
    menuTaskList.clear();
}

extern "C" void on_delete_menu(GtkMenuShell *menushell, gpointer user_data)
{
    MenuListClear();
}


extern "C" void tray_icon_on_menu(GtkStatusIcon *status_icon, guint button, guint activate_time, gpointer user_data)
{
    if ( InvulgoTrackerApp::app->BlockMenu())
        return;
    GtkWidget *menu = gtk_menu_new();
    GtkWidget *item;

    MenuListClear();

    /* Show/Hide */
    if (visible)
        item = gtk_menu_item_new_with_label(_("Hide"));
    else
        item = gtk_menu_item_new_with_label(_("Show"));
    gtk_widget_show(item);
    g_signal_connect(GTK_OBJECT (item), "activate", G_CALLBACK (tray_icon_on_click), user_data);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);

    /* Task */
    item = gtk_menu_item_new_with_label(_("Tasks"));
    gtk_widget_show(item);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);

    InvulgoTrackerApp::app->BuildTaskMenu(item, G_CALLBACK (popupmenu_taskselect), menuTaskList);

    /* Exit */
    //item = gtk_menu_item_new_with_label(_("Quit"));
    item = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, NULL);
    gtk_widget_show(item);
    g_signal_connect(GTK_OBJECT (item), "activate", G_CALLBACK (destroy), user_data);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);

    /* About */
    item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ABOUT, NULL);
    gtk_widget_show(item);
    g_signal_connect(GTK_OBJECT (item), "activate", G_CALLBACK (on_about_activate), user_data);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);

    /* Seperator */
    item = gtk_separator_menu_item_new();
    gtk_widget_show(item);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);

    /* Recent tasks. */
    RecentTasks rt;
    TaskId ti;
    if (rt.GetFirst(ti)) {
        do {
            gchar *name = NULL;
            InvulgoTrackerApp::app->GetTaskView().Get(ti, &name);
            if (name) {
                item = gtk_menu_item_new_with_label(name);
                g_free(name);
                gtk_widget_show(item);
                TaskId *tiptr = new TaskId(ti);
                menuTaskList.push_back(tiptr);
                g_signal_connect(GTK_OBJECT (item), "activate", G_CALLBACK (popupmenu_taskselect), tiptr);
                gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
            }
        } while(rt.GetNext(ti));
    }

    g_signal_connect(GTK_OBJECT (menu), "selection-done", G_CALLBACK (on_delete_menu), user_data);
    gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, button, activate_time);

    //gtk_widget_destroy(menu);
}

gboolean tray_icon_tooltip(GtkStatusIcon *status_icon, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, gpointer user_data)
{
    InvulgoTrackerApp::app->SetTooltip(tooltip);
    return TRUE;
}


void InvulgoTrackerApp::CreateTrayIcon()
{
    char filename[PATH_MAX+1];

    trayIcon = gtk_status_icon_new();
    g_signal_connect(G_OBJECT(trayIcon), "activate", G_CALLBACK(tray_icon_on_click), mainWindow);
    g_signal_connect(G_OBJECT(trayIcon), "popup-menu", G_CALLBACK(tray_icon_on_menu), mainWindow);
    g_signal_connect(G_OBJECT(trayIcon), "query-tooltip", G_CALLBACK(tray_icon_tooltip), mainWindow);

    strcpy(filename, PACKAGE_DATA_DIR);
    strcat(filename, "/pixmaps/InvulgoTracker.png");
    gtk_status_icon_set_from_file(trayIcon, filename);
    gtk_status_icon_set_tooltip_markup(trayIcon, "<b>InvulgoTracker</b>");
    gtk_status_icon_set_visible(trayIcon, TRUE);
}


void InvulgoTrackerApp::InsertEndTask()
{
    Prefs prefs;

    if (prefs.GetInsertEndTask()) {
        TaskTime tt;

        timeView.SetDate(tt.GetYear(),tt.GetMonth(), tt.GetDay());
        timeView.Load();
        timeView.Add(prefs.GetEndTaskId());
        timeView.Save();
    }
}



void quitproc(int code)
{
    InvulgoTrackerApp::app->Exit();
}



void InvulgoTrackerApp::UsedCalcDone()
{
    if (timeUsedCalc) {
        /* Update parent summaries. */
        timeUsedCalc->UpdateParents(taskView);

        /* Process result. */
        timeUsedCalc->UpdateView(timeView, taskView);

        /* Clean */
        delete timeUsedCalc;
        timeUsedCalc = NULL;
        gtk_statusbar_pop(GTK_STATUSBAR(statusBar), 1);
    }
}

void InvulgoTrackerApp::Run()
{
    /* Create dir. */
    const gchar *homeDir = g_get_home_dir();
    gchar *filename = new gchar[PATH_MAX+1];
    strcpy(filename,homeDir);
    strcat(filename, "/.InvulgoTracker");
    mkdir(filename, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IROTH);


    /* Setup main window. */
    CreateMainWindow();
    char title[201];
    strcpy(title, "InvulgoTracker v");
    strcat(title, VERSION);
    gtk_window_set_title(GTK_WINDOW(mainWindow),title);

    // Setup icons
    GList *list = NULL;
    strcpy(filename, PACKAGE_DATA_DIR);
    strcat(filename, "/pixmaps/InvulgoTracker.png");
    GdkPixbuf *pix = gdk_pixbuf_new_from_file(filename,NULL);
    list = g_list_prepend (list, pix);
    strcpy(filename, PACKAGE_DATA_DIR);
    strcat(filename, "/pixmaps/InvulgoTracker16.png");
    pix = gdk_pixbuf_new_from_file(filename,NULL);
    list = g_list_prepend (list, pix);
    strcpy(filename, PACKAGE_DATA_DIR);
    strcat(filename, "/pixmaps/InvulgoTracker48.png");
    pix = gdk_pixbuf_new_from_file(filename,NULL);
    list = g_list_prepend (list, pix);
    strcpy(filename, PACKAGE_DATA_DIR);
    strcat(filename, "/pixmaps/InvulgoTracker64.png");
    pix = gdk_pixbuf_new_from_file(filename,NULL);
    list = g_list_prepend (list, pix);
    gtk_window_set_icon_list(GTK_WINDOW(mainWindow), list);
    delete[] filename;

    SetSavedSizes();
    gtk_widget_hide(mainWindow);

    /* Setup tray. */
    CreateTrayIcon();

    UpdateSummary(timeView.GetYear(), timeView.GetMonth(), timeView.GetDay());

    /* Handle interrupted closure. */
    signal(SIGINT, quitproc);
    signal(SIGQUIT, quitproc);
    signal(SIGHUP, quitproc);

    /* Main loop */
    gtk_main ();

    /* Optional insert end task. */
    InsertEndTask();
}

extern "C" gboolean InvulgoTrackerApp::time_handler(InvulgoTrackerApp *t)
{
    if (t->timeUsedCalc && t->timeUsedCalc->IsDone()) {
        t->UsedCalcDone();
        return false;
    }
    return true;
}

void InvulgoTrackerApp::UpdateSummary(int year, int month, int day)
{
    TaskTime tt;
    if (year ==tt.GetYear() && month == tt.GetMonth() && day == tt.GetDay()) {
        lastTaskId = 0;
    }
    summaryView.CalcDay(year, month, day);

    if (year ==tt.GetYear() && month == tt.GetMonth() && day == tt.GetDay()) {
        lastTaskId = summaryView.GetLastTaskId();
        lastTaskTime = summaryView.GetLastTime();
    }
    /* Start task time usage collection thread. */
    if (timeUsedCalc) {
        delete timeUsedCalc;
        timeUsedCalc = NULL;
        gtk_statusbar_pop(GTK_STATUSBAR(statusBar), 1);
    }
    timeUsedCalc = new TimeUsedThread();
    if (timeUsedCalc->Start()) {
        delete timeUsedCalc;
        timeUsedCalc = NULL;
    } else {
        gtk_statusbar_push(GTK_STATUSBAR(statusBar), 1, _("Updating..."));
        g_timeout_add(100, (GSourceFunc) time_handler, (gpointer) this);
    }

    WorkBalance wb(year, month, day);
    char txt[21];

    sprintf(txt, "%d", wb.GetMonthToDateBalance());
    GtkWidget  *widget;
    widget = glade_xml_get_widget (InvulgoTrackerApp::gxml, "entryWorkbalance");
    gtk_entry_set_text(GTK_ENTRY(widget), txt);
}


void InvulgoTrackerApp::TimeSaveAndCalc()
{
    timeView.Save();
    UpdateSummary(timeView.GetYear(), timeView.GetMonth(), timeView.GetDay());
}


void InvulgoTrackerApp::AddTimeByPath(GtkTreePath *path)
{
    timeView.Add(path);
    TimeSaveAndCalc();
}

void InvulgoTrackerApp::TimeEdit(gchar *pathString, gchar *newText)
{
    timeView.Edit(pathString, newText);
    TimeSaveAndCalc();
}

void InvulgoTrackerApp::TaskEdit(gchar *pathString, gchar *newText)
{
    taskView.Edit(pathString, newText);
    taskView.Save();
}

void InvulgoTrackerApp::TimeDelete()
{
    timeView.Delete();
    TimeSaveAndCalc();
}

void InvulgoTrackerApp::TaskDelete()
{
    taskView.Delete();
    taskView.Save();
}

void InvulgoTrackerApp::TaskAdd()
{
    taskView.Add();
    taskView.Save();
}

void InvulgoTrackerApp::TaskAddRoot()
{
    taskView.AddRoot();
    taskView.Save();
}

void InvulgoTrackerApp::AboutShow()
{
    About *about = new About();

    about->Show();
}

void InvulgoTrackerApp::HelpShow()
{
    gnome_vfs_url_show("http://code.google.com/p/invulgotracker/wiki/InvulgoTracker");
}

void InvulgoTrackerApp::AddTimeByTask(TaskId taskId)
{
    timeView.Add(taskId);
    TimeSaveAndCalc();
}

void InvulgoTrackerApp::BuildTaskMenu(GtkWidget *item, GCallback callback, list<TaskId *> &menuTaskList)
{
    taskView.BuildMenu(item, callback, menuTaskList);
}


void InvulgoTrackerApp::TimeAdd()
{
    timeView.Add();
    TimeSaveAndCalc();
}

void InvulgoTrackerApp::TimeInsert()
{
    timeView.Insert();
    TimeSaveAndCalc();
}


void InvulgoTrackerApp::CalendarSelected(GtkCalendar *calendar)
{
    guint year, month, day;

    gtk_calendar_get_date(calendar, &year, &month, &day);
    timeView.SetDate(year, month, day);
    timeView.Load();
    UpdateSummary(year, month, day);
}

void InvulgoTrackerApp::SetSickday()
{
    Prefs prefs;
    guint year, month, day;
    GtkCalendar *calendar = (GtkCalendar*)glade_xml_get_widget (InvulgoTrackerApp::gxml, "calendar");
    gtk_calendar_get_date(calendar, &year, &month, &day);
    TaskTime today(year, month + 1, day);
    int weekday = today.GetWeekDay();

    if (prefs.GetHolidayTaskId() && prefs.GetEndTaskId()) {
        if (!timeView.Find(prefs.GetSickTaskId())) {
            timeView.Load();
            timeView.AddNoCheck(prefs.GetSickTaskId(), TaskTime(prefs.GetWorkdayStart(weekday)));
            timeView.AddNoCheck(prefs.GetEndTaskId(), TaskTime(prefs.GetWorkdayEnd(weekday)));
            timeView.Save();
        }
    }
}

void InvulgoTrackerApp::SetHoliday()
{
    Prefs prefs;
    guint year, month, day;
    GtkCalendar *calendar = (GtkCalendar*)glade_xml_get_widget (InvulgoTrackerApp::gxml, "calendar");
    gtk_calendar_get_date(calendar, &year, &month, &day);
    TaskTime today(year, month + 1, day);
    int weekday = today.GetWeekDay();

    if (prefs.GetHolidayTaskId() && prefs.GetEndTaskId()) {
        if (!timeView.Find(prefs.GetHolidayTaskId())) {
            timeView.Load();
            timeView.AddNoCheck(prefs.GetHolidayTaskId(), TaskTime(prefs.GetWorkdayStart(weekday)));
            timeView.AddNoCheck(prefs.GetEndTaskId(), TaskTime(prefs.GetWorkdayEnd(weekday)));
            timeView.Save();
        }
    }
}

void InvulgoTrackerApp::Notify(int event)
{
    if (event == Prefs::SAVED) {
        Prefs prefs;
        taskView.Refilter();
        if (prefs.GetShowSummaryPercentage() != savePrefsShowSummaryPercentage) {
            summaryView.Restart();
            UpdateSummary(timeView.GetYear(), timeView.GetMonth(), timeView.GetDay());
        }
        if (prefs.GetColorDeadline() != saveColorDeadline
            || prefs.GetColorDone() != saveColorDone) {
            taskView.Restart();
            UpdateSummary(timeView.GetYear(), timeView.GetMonth(), timeView.GetDay());
        }

    } else if (event == TaskDetailDlg::SAVED) {
        UpdateSummary(timeView.GetYear(), timeView.GetMonth(), timeView.GetDay());
    }
}

void InvulgoTrackerApp::ShowPrefs()
{
    Prefs *prefs = new Prefs();

    savePrefsShowSummaryPercentage = prefs->GetShowSummaryPercentage();
    saveColorDeadline = prefs->GetColorDeadline();
    saveColorDone = prefs->GetColorDone();
    prefs->Show(this);
}

void InvulgoTrackerApp::TaskDetails()
{
    gchar *name;
    TaskId id;
    if (taskView.GetSelected(&name, id)) {
        g_free(name);
        TaskDetailDlg *tdd = new TaskDetailDlg(&taskView, id);
        tdd->Show(this);
    }
}


extern "C" void on_treeviewTask_row_activated(GtkTreeView *tree_view,GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data)
{
    InvulgoTrackerApp::app->AddTimeByPath(path);
}

extern "C" gboolean on_treeviewTime_key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
{
    if (event->keyval == GDK_Delete) {
        InvulgoTrackerApp::app->TimeDelete();
        return TRUE;
    }
    return FALSE;
}

extern "C" gboolean on_treeviewTask_key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
{
    if (event->keyval == GDK_Delete) {
        InvulgoTrackerApp::app->TaskDelete();
        return TRUE;
    }
    return FALSE;
}



extern "C" void on_toolbuttonQuit_clicked(GtkMenuItem *menu_item)
{
    InvulgoTrackerApp::app->Exit();
}


extern "C" void on_quit1_activate(GtkMenuItem *menu_item)
{
    InvulgoTrackerApp::app->Exit();
}





extern "C" gboolean on_InvulgoTracker_delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
    Prefs prefs;

    if (prefs.GetHideOnClose()) {
        visible = FALSE;
        gtk_widget_hide(widget);
        return TRUE;
    }
    InvulgoTrackerApp::app->Exit();
    return FALSE;
}



extern "C" gboolean on_InvulgoTracker_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer trayIcon)
{
    Prefs prefs;

    currentState = event->new_window_state;

    if (prefs.GetSaveWindowSizes()) {
        if (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED && !prefs.GetSavedWindowMaximized()) {
            prefs.SetSavedWindowMaximized(true);
            prefs.Save();
        } else if (prefs.GetSavedWindowMaximized()) {
            prefs.SetSavedWindowMaximized(false);
            prefs.Save();
        }
    }

    if (prefs.GetHideOnMinimize() && event->changed_mask == GDK_WINDOW_STATE_ICONIFIED && (event->new_window_state == GDK_WINDOW_STATE_ICONIFIED || event->new_window_state == (GDK_WINDOW_STATE_ICONIFIED | GDK_WINDOW_STATE_MAXIMIZED))) {
        visible = FALSE;
        gtk_widget_hide (GTK_WIDGET(widget));
    }
    return TRUE;
}




extern "C" void on_toolbuttonPrefs_clicked(GtkButton *button, gpointer user_data)
{
    InvulgoTrackerApp::app->ShowPrefs();
}

extern "C" void on_preferences_activate(GtkButton *button, gpointer user_data)
{
    InvulgoTrackerApp::app->ShowPrefs();
}

extern "C" void on_buttonAdd_clicked(GtkButton *button, gpointer user_data)
{
    InvulgoTrackerApp::app->TaskAdd();
}

extern "C" void on_buttonDelete_clicked(GtkButton *button, gpointer user_data)
{
    InvulgoTrackerApp::app->TaskDelete();
}

extern "C" void on_buttonAddRoot_clicked(GtkButton *button, gpointer user_data)
{
    InvulgoTrackerApp::app->TaskAddRoot();
}


extern "C" void on_buttonAddTime_clicked(GtkButton *button, gpointer user_data)
{
    InvulgoTrackerApp::app->TimeAdd();
}

extern "C" void on_buttonInsertTime_clicked(GtkButton *button, gpointer user_data)
{
    InvulgoTrackerApp::app->TimeInsert();
}

extern "C" void on_buttonDeleteTime_clicked(GtkButton *button, gpointer user_data)
{
    InvulgoTrackerApp::app->TimeDelete();
}

extern "C" void on_calendar_day_selected(GtkCalendar *calendar, gpointer user_data)
{
    InvulgoTrackerApp::app->CalendarSelected(calendar);
}

extern "C" void on_buttonToday_clicked(GtkButton *button, gpointer user_data)
{
    GtkCalendar *calendar = (GtkCalendar*)glade_xml_get_widget (InvulgoTrackerApp::gxml, "calendar");

    TaskTime tt;

    gtk_calendar_select_month(calendar, tt.GetMonth(), tt.GetYear());
    gtk_calendar_select_day(calendar, tt.GetDay());
}

extern "C" void on_buttonSickday_clicked(GtkButton *button, gpointer user_data)
{
    InvulgoTrackerApp::app->SetSickday();
}

extern "C" void on_buttonHoliday_clicked(GtkButton *button, gpointer user_data)
{
    InvulgoTrackerApp::app->SetHoliday();
}

extern "C" gboolean on_InvulgoTracker_configure_event(GtkWidget  *widget, GdkEventConfigure *event, gpointer user_data)
{
    Prefs prefs;

    if (prefs.GetSaveWindowSizes() && event->type == GDK_CONFIGURE && !(currentState & GDK_WINDOW_STATE_MAXIMIZED)) {
        if (prefs.GetSavedWindowWidth() != event->width
            || prefs.GetSavedWindowHeight() != event->height) {
            prefs.SetSavedWindowWidth(event->width);
            prefs.SetSavedWindowHeight(event->height);
            prefs.Save();
            }
    }
    return FALSE;
}

extern "C" void on_vpanedTimeDate_size_allocate(GtkWidget *widget, GtkAllocation *allocation, gpointer user_data)
{
    Prefs prefs;

    if (prefs.GetSaveWindowSizes()) {
        GtkWidget  *window;
        window = glade_xml_get_widget (InvulgoTrackerApp::gxml, "vpanedTimeDate");
        if (gtk_paned_get_position(GTK_PANED(window)) != prefs.GetSavedVPanePosition()) {
            prefs.SetSavedVPanePosition(gtk_paned_get_position(GTK_PANED(window)));
            prefs.Save();
        }
    }

}

extern "C" void on_hpanedTaskTime_size_allocate(GtkWidget *widget, GtkAllocation *allocation, gpointer user_data)
{
    Prefs prefs;

    if (prefs.GetSaveWindowSizes()) {
        GtkWidget  *window;
        window = glade_xml_get_widget (InvulgoTrackerApp::gxml, "hpanedTaskTime");
        if (gtk_paned_get_position(GTK_PANED(window)) != prefs.GetSavedHPanePosition()) {
            prefs.SetSavedHPanePosition(gtk_paned_get_position(GTK_PANED(window)));
            prefs.Save();
        }
    }

}

extern "C" void on_toolbuttonReport_clicked(GtkButton *button, gpointer user_data)
{
    Report *report = Report::GetReport();
    report->Show();
}


extern "C" void on_buttonTaskEdit_clicked(GtkButton *button, gpointer user_data)
{
    InvulgoTrackerApp::app->TaskDetails();
}

